/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.metadata.rtcustomization.context;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.metadata.rtcustomization.api.entity.ConfigDataDependenciesEnum;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

/**
 * 元数据复制服务上下文服务类
 */
public class MimicServiceContextHolder {
    /**
     * 元数据服务上下文
     */
    private static final ThreadLocal<MimicServiceContext> mimcServiceContext = InheritableThreadLocal.withInitial(() -> null);

    private MimicServiceContextHolder() {
    }

    /**
     * 根据旧UUID查找新UUID
     *
     * @param oldUUID
     * @return
     */
    public static String findNewUUID(String oldUUID) {
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        return getCurrentContext().get().getOldUUID2NewUUIDMap().get(oldUUID);
    }

    /**
     * 保存旧UUID-新UUID的关系
     *
     * @param oldUUID
     * @param newUUID
     */
    public static void saveUUID(String oldUUID, String newUUID) {
        Assert.notNull(oldUUID, "参数错误, 旧UUID不允许为空");
        Assert.notNull(newUUID, "参数错误, 新UUID不允许为空");
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        getCurrentContext().get().getOldUUID2NewUUIDMap().put(oldUUID, newUUID);
    }

    /**
     * 通过配置数据变量查找新值
     *
     * @param columnVariable
     * @return
     */
    public static String findConfigDataNewValue(String columnVariable) {
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        return getCurrentContext().get().getColumnVariable2NewValueMap().get(columnVariable.toLowerCase());
    }

    /**
     * 保存配置数据变量-新值映射关系
     *
     * @param columnVariable
     * @param columnNewValue
     */
    public static void saveConfigData(String columnVariable, String columnNewValue) {
        Assert.notNull(columnVariable, "参数错误, 列变量不允许为空");
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        getCurrentContext().get().getColumnVariable2NewValueMap().put(columnVariable.toLowerCase(), columnNewValue);
    }

    /**
     * 根据配置数据依赖类型，查找依赖的配置数据
     *
     * @param configDataDependenciesEnum
     * @return
     */
    public static List<String> findConfigDataDependencies(ConfigDataDependenciesEnum configDataDependenciesEnum) {
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        Set<String> result = getCurrentContext().get().getConfigDataDependenciesEnumListMap().get(configDataDependenciesEnum);
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        return result.stream().collect(Collectors.toList());
    }

    /**
     * 保存元数据上的配置数据依赖项
     *
     * @param configDataDependenciesEnumListMap
     * @return
     */
    public static void saveConfigDataDependencies(
        Map<ConfigDataDependenciesEnum, Set<String>> configDataDependenciesEnumListMap) {
        if (CollectionUtils.isEmpty(configDataDependenciesEnumListMap)) {
            return;
        }
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        for (ConfigDataDependenciesEnum configDataDependenciesEnum : ConfigDataDependenciesEnum.values()) {
            Set<String> result = configDataDependenciesEnumListMap.get(configDataDependenciesEnum);
            if (CollectionUtils.isEmpty(result)) {
                continue;
            }
            if (CollectionUtils.isEmpty(getCurrentContext().get().getConfigDataDependenciesEnumListMap().get(configDataDependenciesEnum))) {
                getCurrentContext().get().getConfigDataDependenciesEnumListMap().put(configDataDependenciesEnum, result);
            } else {
                getCurrentContext().get().getConfigDataDependenciesEnumListMap().get(configDataDependenciesEnum).addAll(result);
            }
        }
    }

    /**
     * 根据原始元数据ID，查询复制后的元数据
     *
     * @param originalMetadataId
     * @return
     */
    public static GspMetadata findCopiedGspMetadata(String originalMetadataId) {
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        return getCurrentContext().get().getOriginalMetadataId2GspMetadataAfterCopyMap().get(originalMetadataId);
    }

    /**
     * 保存已复制的元数据
     *
     * @param gspMetadata:此处元数据uuid未复制，依然是旧值
     * @return
     */
    public static void saveCopiedGspMetadata(GspMetadata gspMetadata) {
        if (Objects.isNull(gspMetadata)) {
            return;
        }
        if (!getCurrentContext().isPresent()) {
            MimicServiceContextHolder.setCurrentContext(MimicServiceContext.ofMimicServiceContext());
        }
        getCurrentContext().get().getOriginalMetadataId2GspMetadataAfterCopyMap().put(gspMetadata.getHeader().getId(), gspMetadata);
    }

    public static void setCurrentContext(MimicServiceContext context) {
        if (Objects.nonNull(context)) {
            mimcServiceContext.set(context);
        }
    }

    /**
     * 清除
     */
    public static void purge() {
        mimcServiceContext.remove();
    }

    public static Optional<MimicServiceContext> getCurrentContext() {
        return Optional.ofNullable(mimcServiceContext.get());
    }
}
